﻿using DFGK.WMS.Common.Extensions;
using DFGK.WMS.Common.Result;
using DFGK.WMS.Common.Tools;
using DFGK.WMS.Common.Web;
using DFGK_WMS.Context;
using DFGK_WMS.IRepository;
using DFGK_WMS.IRepository.IService;
using DFGK_WMS.Model;
using DFGK_WMS.Model.DTO;
using DFGK_WMS.Model.Enum;
using DFGK_WMS.Model.Models;
using DFGK_WMS.Model.Models.PDA;
using DFGK_WMS.WebAPI.Tools;
using Dm;
using Microsoft.EntityFrameworkCore;
using NetTaste;
using NPOI.POIFS.Crypt.Dsig;
using NPOI.SS.Formula.Functions;
using NPOI.SS.Formula.PTG;
using Org.BouncyCastle.Bcpg;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace DFGK_WMS.Repository.Service
{
    public class StackingStorageService : BaseService, IStackingStorageService
    {
        protected readonly static object _lockObj = new object();

        public ITCellRepository TCellRepository { get; }
        public DFGK_DB Context { get; }

        public StackingStorageService(ISqlSugarClient client, ITCellRepository tCellRepository, DFGK_DB context) : base(client)
        {
            TCellRepository = tCellRepository;
            Context = context;
        }

        public bool BuildCreateStackingStorage(out string errMsg, PalletTallyInputModel data)
        {
            errMsg = string.Empty;
            (bool, string, TReceivingOrderDetail) arr = ValidateStatus(data.OrderDetailId);

            if (arr.Item1 == false)
            {
                errMsg = arr.Item2;
                return false;
            }
            TReceivingOrderDetail? item3 = arr.Item3;

            int heightType = (int)EmHeightType.H1150;
            decimal enabledNum = item3.Qty.GetValueOrDefault() - item3.StackedQty.GetValueOrDefault();
            if (enabledNum - data.TotalNum < 0 || data.TotalNum <= 0)
            {
                errMsg = "数量超出，最多还能组" + enabledNum.ToString() + item3.UnitName;
                return false;
            }
            var material = this._Client.Queryable<TMaterial>().InSingle(item3.MaterialId);

            if (material == null)
            {
                errMsg = "未找到物料数据";
                return false;

            }

            if (material.Code != data.PalletPackage.MaterialCode)
            {
                errMsg = "包装信息中的物料与单据物料不一致";
                return false;
            }

            #region 注释
            //if (data.PalletPackages.Select(t => t.MaterialCode).Distinct().Count() > 1)
            //{
            //    errMsg = "物料号存在多种";
            //    return false;
            //    return Result("", ResultCode.Error);
            //}
            //if (data.PalletPackages.Select(t => t.OrderSN).Distinct().Count() > 1 || data.PalletPackages.Select(t => t.OrderLineSN).Distinct().Count() > 1)
            //{
            //    return Result("物料号存在多个订单编号", ResultCode.Error);
            //}
            #endregion
            Model.Models.PalletBindMaterialModel palletBindMaterialModel = new Model.Models.PalletBindMaterialModel()
            {
                PalletBarcode = data.PalletBarcode,
                LogicPartCode = data.LogicPartCode,
                MaterialPackageBindModel = new Model.Models.MaterialPackageBindModel()
                {
                    OrderDetailId = data.OrderDetailId.Value,
                    MaterialCode = data.PalletPackage.MaterialCode,
                    Barcodes = data.PalletPackage.Barcodes,
                    Qty = data.TotalNum,
                }
            };

            TStation station = _Client.Queryable<TStation>().First(r => r.WhId == data.WarehouseId);
            if (station is null)
            {
                errMsg = "请配置站台";
                return false;
            }

            TStackingStorage storageModel = _Client.Queryable<TStackingStorage>().First(r => r.Status == 1 && r.PalletBarcode == data.PalletBarcode);
            if (storageModel != null)
            {
                errMsg = "托盘已在组垛中";
                return false;
            }
            string palletBarcode = palletBindMaterialModel.PalletBarcode;
            List<string> palletBarcodeList = palletBarcode.StringToList();
            if (palletBarcodeList != null && palletBarcodeList.Count > 0)
            {
                palletBarcode = palletBarcodeList[0];
                palletBarcodeList.Remove(palletBarcode);
            }
            int OrderId = palletBindMaterialModel.MaterialPackageBindModel.OrderDetailId;
            var orderDetail = _Client.Queryable<TReceivingOrderDetail>().First(x => x.Id == OrderId);
            decimal? materialNum = 0;
            materialNum = palletBindMaterialModel.MaterialPackageBindModel.Qty;
            try
            {
                int stackingId = 0;
                string LogicPartCode = "";
                _Client.Ado.BeginTran();
                var tackingStorage = _Client.Queryable<TStackingStorage>().First(x => x.PalletBarcode == palletBarcode && x.RelatedOrderDetailId == OrderId && x.WarehouseCode == orderDetail.WarehouseCode && x.Status == 1);
                if (tackingStorage != null && tackingStorage.Id > 0)
                {
                    stackingId = tackingStorage.Id;
                }
                else
                {
                    var cell = GetOneCell(station, orderDetail, heightType, out string errorMsg, palletBindMaterialModel);
                    if (cell == null)
                    {
                        errorMsg = errorMsg;
                        return false;
                    }
                    var pallet = _Client.Queryable<TPallet>().First(x => x.PalletBarcode == palletBarcode);

                    if (pallet is null || string.IsNullOrWhiteSpace(pallet.PalletBarcode))
                    {
                        errMsg = "当前托盘不存在";
                        _Client.Ado.RollbackTran();
                        return false;
                    }
                    if (pallet.Type == (int)PalletTypeEnum.Pallet)
                    {
                        LogicPartCode = "TuoPan";
                    }
                    else if (pallet.Type == (int)PalletTypeEnum.Box64)
                    {
                        LogicPartCode = "Box6040";
                    }
                    else if (pallet.Type == (int)PalletTypeEnum.Box86)
                    {
                        LogicPartCode = "Box8060";
                    }

                    int stackingStorage = _Client.Insertable<TStackingStorage>(new TStackingStorage()
                    {
                        WarehouseName = orderDetail.WarehouseName,
                        WarehouseCode = orderDetail.WarehouseCode,
                        BillType = (int)orderDetail.BillType.GetValueOrDefault(),
                        RelatedOrderDetailId = OrderId,
                        Status = 1,
                        PalletBarcode = palletBarcode,
                        Qty = materialNum,
                        PackQty = 1,
                        AreaCode = "",
                        LogicalPartCode = LogicPartCode,
                        MaterialId = orderDetail.MaterialId,
                        MaterialCode = orderDetail.MaterialCode,
                        MaterialName = orderDetail.MaterialName,
                        MaterialKeyId = orderDetail.MaterialKeyId,
                        CreateUserId = data.UserId,
                        CreateUserName = data.UserName,
                        BatchNo = orderDetail.BatchNo,
                        CreateDate = DateTime.Now,
                        Fifodate = DateTime.Now,
                        ExpectedLocation = cell.Code
                    }).ExecuteCommand();

                    if (stackingStorage <= 0)
                    {
                        errMsg = "保存垛主表数据失败";
                        _Client.Ado.RollbackTran();
                        return false;
                    }

                    #region 垛包装数据保存
                    if (palletBarcodeList != null && palletBarcodeList.Count > 0)
                    {
                        foreach (var itemPalletBarcode in palletBarcodeList)
                        {
                            var pallet1 = _Client.Queryable<TPallet>().First(x => x.PalletBarcode == itemPalletBarcode);
                            if (pallet is null || string.IsNullOrWhiteSpace(pallet.PalletBarcode))
                            {
                                errMsg = "当前托盘不存在";
                                _Client.Ado.RollbackTran();
                                return false;
                            }
                            if (pallet.Type == (int)PalletTypeEnum.Pallet)
                            {
                                LogicPartCode = "TuoPan";
                            }
                            else if (pallet.Type == (int)PalletTypeEnum.Box64)
                            {
                                LogicPartCode = "Box6040";
                            }
                            else if (pallet.Type == (int)PalletTypeEnum.Box86)
                            {
                                LogicPartCode = "Box8060";
                            }
                            int chStackingId = _Client.Insertable<TStackingStorage>(new TStackingStorage()
                            {
                                WarehouseName = orderDetail.WarehouseName,
                                WarehouseCode = orderDetail.WarehouseCode,
                                BillType = (int)orderDetail.BillType.GetValueOrDefault(),
                                RelatedOrderDetailId = OrderId,
                                Status = 1,
                                PalletBarcode = itemPalletBarcode,
                                Qty = materialNum,
                                PackQty = 1,
                                AreaCode = "",
                                LogicalPartCode = LogicPartCode,
                                MaterialId = orderDetail.MaterialId,
                                MaterialCode = orderDetail.MaterialCode,
                                MaterialName = orderDetail.MaterialName,
                                MaterialKeyId = orderDetail.MaterialKeyId,
                                CreateUserId = data.UserId,
                                CreateUserName = data.UserName,
                                BatchNo = orderDetail.BatchNo,
                                CreateDate = DateTime.Now,
                                Fifodate = DateTime.Now,
                                ParentPalletBarcode = palletBarcode,
                                ExpectedLocation = cell.Code
                            }).ExecuteCommand();
                            if (chStackingId <= 0)
                            {
                                errMsg = "保存垛主表数据失败";
                                _Client.Ado.RollbackTran();
                                return false;
                            }
                        }
                    }

                    /*
                    List<string> barCodes = new List<string>();
                    orderDetail = _Client.Queryable<TReceivingOrderDetail>().First(x => x.Id == palletBindMaterialModel.MaterialPackageBindModel.OrderDetailId);

                    TPackageDetail packageContainer = _Client.Queryable<TPackageDetail>().First(x => x.PackageCode == palletBarcode && x.StackingStorageId == stackingId && x.Status == 1 && x.RelatedOrderDetailId == orderDetail.Id);
                    if (packageContainer != null)
                    {
                        //if (palletBindMaterialModel.MaterialPackageBindModel.Barcodes != null && palletBindMaterialModel.MaterialPackageBindModel.Barcodes.Count > 0)
                        //{
                        //    packageContainer.HasSkuDetail = palletBindMaterialModel.MaterialPackageBindModel.Barcodes.Count() > 0;
                        //    packageContainer.SkuNum = palletBindMaterialModel.MaterialPackageBindModel.Barcodes.Count();
                        //}
                    }
                    else
                    {
                        packageContainer = new TPackageDetail()
                        {
                            Status = 1,
                            RelatedOrderDetailId = orderDetail.Id,
                            MaterialId = orderDetail.MaterialId,
                            MaterialKeyId = orderDetail.MaterialKeyId,
                            MaterialCode = orderDetail.MaterialCode,
                            MaterialName = orderDetail.MaterialName,
                            PackageClass = 1,// package.PackageSkuBindList != null && package.PackageSkuBindList.Count > 0 ? 1 : 2,
                            BatchNo = orderDetail.BatchNo,
                            Qty = palletBindMaterialModel.MaterialPackageBindModel.Qty,
                            UnitId = orderDetail.UnitId,
                            UnitName = orderDetail.UnitName,
                            ConvertFigre = 0,
                            PackageCode = palletBarcode,// package.PackageBarcode
                            StackingStorageId = stackingId,
                            LayerIndex = 1,
                            CreateDate = DateTime.Now,
                            ParentId = 0,
                            IsStocktake = false,
                            CreateUserId = data.UserId.GetValueOrDefault(),
                            CreateUserName = data.UserName,
                        };
                        //if (palletBindMaterialModel.MaterialPackageBindModel.Barcodes != null && palletBindMaterialModel.MaterialPackageBindModel.Barcodes.Count > 0)
                        //{
                        //    packageContainer.HasSkuDetail = palletBindMaterialModel.MaterialPackageBindModel.Barcodes.Count() > 0;
                        //    packageContainer.SkuNum = palletBindMaterialModel.MaterialPackageBindModel.Barcodes.Count();
                        //}
                        int pkgId = _Client.Insertable<TPackageDetail>(packageContainer).ExecuteCommand();
                        if (pkgId <= 0)
                        {
                            errMsg = "保存组箱数据失败";
                            _Client.Ado.RollbackTran();
                            return false;
                        }
                    }
                    */
                    /* 注释
                    //if (palletBindMaterialModel.MaterialPackageBindModel.Barcodes != null && palletBindMaterialModel.MaterialPackageBindModel.Barcodes.Count > 0)
                    //{
                    //    barCodes = palletBindMaterialModel.MaterialPackageBindModel.Barcodes;
                    //    foreach (string barcode in palletBindMaterialModel.MaterialPackageBindModel.Barcodes)
                    //    {
                    //        TPackageDetail sku = new TPackageDetail()
                    //        {
                    //            Status = 1,
                    //            RelatedOrderDetailId = orderDetail.Id,
                    //            MaterialId = orderDetail.MaterialId,
                    //            MaterialKeyId = orderDetail.MaterialKeyId,
                    //            MaterialCode = orderDetail.MaterialCode,
                    //            MaterialName = orderDetail.MaterialName,
                    //            PackageClass = 2,
                    //            BatchNo = orderDetail.BatchNo,
                    //            Qty = 1,
                    //            UnitId = orderDetail.UnitId,
                    //            UnitName = orderDetail.UnitName,
                    //            ConvertFigre = 0,
                    //            Barcode = barcode,
                    //            PackageCode = palletBarcode,
                    //            LayerIndex = 1,
                    //            CreateDate = DateTime.Now,
                    //            StackingStorageId = stackingId,
                    //            ParentId = packageContainer.Id,
                    //            IsStocktake = false,
                    //            CreateUserId = data.UserId.GetValueOrDefault(),
                    //            CreateUserName = data.UserName,
                    //        };
                    //        int skuPkgId = _Client.Insertable<TPackageDetail>(sku).ExecuteCommand();
                    //        if (skuPkgId <= 0)
                    //        {
                    //            errMsg = "保存组箱数据失败";
                    //            _Client.Ado.RollbackTran();
                    //            return false;
                    //        }
                    //    }
                    //}
                    */
                    //更新入库单状态
                    TReceivingOrderDetail? receivingOrderDetail = _Client.Queryable<TReceivingOrderDetail>().First(r => r.Id == OrderId);
                    receivingOrderDetail.LogicalPartCode = palletBindMaterialModel.LogicPartCode;
                    receivingOrderDetail.StackedQty = orderDetail.StackedQty + materialNum;
                    //Status = 3,
                    receivingOrderDetail.AuditDate = DateTime.Now;
                    receivingOrderDetail.AuditUserId = data.UserId;
                    receivingOrderDetail.AuditUserName = data.UserName;
                    _Client.Updateable<TReceivingOrderDetail>(receivingOrderDetail);

                    //更新货货品明细
                    //if (barCodes.Count > 0)
                    //{

                    //    //List<TReceivingGoodsDetail>? receivingGoodDetailList = _Client.Queryable<TReceivingGoodsDetail>().Where(r => //r.OrderDetailId == OrderId && r.Status == 0 && barCodes.Contains(r.Barcode)).ToList();
                    //    List<TReceivingGoodsDetail>? receivingGoodDetailList = _Client.Queryable<TReceivingGoodsDetail>().Where(r => r.OrderDetailId == OrderId && r.Status == 0 && barCodes.Contains(r.Barcode)).ToList();

                    //    if (receivingGoodDetailList.Count != barCodes.Count)
                    //    {
                    //        errMsg = "货品明细与组垛明细数量不一致";
                    //        _Client.Ado.RollbackTran();
                    //        return false;
                    //    }
                    //    else
                    //    {
                    //        foreach (var item in receivingGoodDetailList)
                    //        {
                    //            item.Status = 1;
                    //            item.PalletBarcode = palletBarcode;
                    //            item.PackageBarcode = palletBarcode;
                    //            _Client.Updateable<TReceivingGoodsDetail>(item);
                    //        }
                    //    }
                    //}

                    #endregion

                    //bool isok = ExecCreateInstruct(out errMsg, orderDetail, station, palletBindMaterialModel);
                    //if (!isok)
                    //{
                    //    return false;
                    //}
                    _Client.Ado.CommitTran();
                }
            }
            catch (Exception)
            {
                errMsg = "保存组箱数据失败";
                _Client.Ado.RollbackTran();
                throw;
            }
            return true;
        }

        public bool BuildCreateStackingStorageEF(out string errMsg, PalletTallyInputModel data, ref List<TCell> Getcell)
        {
            errMsg = string.Empty;
            bool result = false;
            (bool, string, TReceivingOrderDetail) arr = ValidateStatusEF(data.OrderDetailId);

            if (arr.Item1 == false)
            {
                errMsg = arr.Item2;
                return false;
            }
            TReceivingOrderDetail? item3 = arr.Item3;

            int heightType = (int)EmHeightType.H1150;
            decimal enabledNum = item3.Qty.GetValueOrDefault() - item3.StackedQty.GetValueOrDefault();
            if (enabledNum - data.TotalNum < 0 || data.TotalNum <= 0)
            {
                errMsg = "数量超出，最多还能组" + enabledNum.ToString() + item3.UnitName;
                return false;
            }
            var material = Context.TMaterials.AsNoTracking().FirstOrDefault(m => m.Id == item3.MaterialId);

            if (material == null)
            {
                errMsg = "未找到物料数据";
                return false;

            }

            if (material.Code != data.PalletPackage.MaterialCode)
            {
                errMsg = "包装信息中的物料与单据物料不一致";
                return false;
            }
            Model.Models.PalletBindMaterialModel palletBindMaterialModel = new Model.Models.PalletBindMaterialModel()
            {
                PalletBarcode = data.PalletBarcode,
                LogicPartCode = data?.LogicPartCode,
                MaterialPackageBindModel = new Model.Models.MaterialPackageBindModel()
                {
                    OrderDetailId = data.OrderDetailId.Value,
                    MaterialCode = data.PalletPackage.MaterialCode,
                    Barcodes = data.PalletPackage.Barcodes,
                    Qty = data.TotalNum,
                }
            };

            TStation station = Context.TStations.FirstOrDefault(r => r.WhId == data.WarehouseId);
            if (station is null)
            {
                errMsg = "请配置站台";
                return false;
            }

            //var storageModellist = Context.TStackingStorages.Where(r => r.Status == 1 && r.PalletBarcode == data.PalletBarcode);
            //if (storageModellist != null && storageModellist.Count() > 3)
            //{
            //    errMsg = "托盘已在组垛中且超出组垛数量";
            //    return false;
            //}
            var getPall = Context.TPallets.FirstOrDefault(x => x.PalletBarcode == data.PalletBarcode);
            if (getPall is null || getPall.Status == 0)
            {
                errMsg = "未查询出此托盘：" + data.PalletBarcode;
                return false;
            }
            if (getPall.Status == 0)
            {
                errMsg = "托盘已被禁用：" + data.PalletBarcode;
                return false;
            }
            string palletBarcode = palletBindMaterialModel.PalletBarcode;
            int OrderId = palletBindMaterialModel.MaterialPackageBindModel.OrderDetailId;
            var orderDetail = Context.TReceivingOrderDetails.FirstOrDefault(x => x.Id == OrderId);
            if (orderDetail == null)
            {
                errMsg = "入库单信息有误：" + OrderId;
                return false;
            }
            decimal? materialNum = 0;
            materialNum = palletBindMaterialModel.MaterialPackageBindModel.Qty;
            try
            {
                int stackingId = 0;
                string LogicPartCode = "";
                string cellcode = "";
                var tackingStorage = Context.TStackingStorages.FirstOrDefault(x => x.PalletBarcode == palletBarcode && x.WarehouseCode == orderDetail.WarehouseCode && x.Status == 1);
                if (tackingStorage != null && tackingStorage.Id > 0)
                {
                    cellcode = tackingStorage.ExpectedLocation;
                }

                var pallet = Context.TPallets.FirstOrDefault(x => x.PalletBarcode == palletBarcode);

                if (pallet is null || string.IsNullOrWhiteSpace(pallet.PalletBarcode))
                {
                    errMsg = "当前托盘不存在";
                    return false;
                }
                if (pallet.Type == (int)PalletTypeEnum.Pallet)
                {
                    LogicPartCode = "TuoPan";
                }
                else if (pallet.Type == (int)PalletTypeEnum.Box64)
                {
                    LogicPartCode = "Box6040";
                }
                else if (pallet.Type == (int)PalletTypeEnum.Box86)
                {
                    LogicPartCode = "Box8060";
                }

                TStackingStorage chStacking = new TStackingStorage();
                #region 垛包装数据保存
                if (palletBarcode != null)
                {
                    chStacking.WarehouseName = orderDetail.WarehouseName;
                    chStacking.WarehouseCode = orderDetail.WarehouseCode;
                    chStacking.BillType = (int)orderDetail.BillType.GetValueOrDefault();
                    chStacking.RelatedOrderDetailId = OrderId;
                    chStacking.Status = 1;
                    chStacking.PalletBarcode = palletBarcode;
                    chStacking.Qty = materialNum;
                    chStacking.PackQty = 1;
                    chStacking.AreaCode = "";
                    chStacking.LogicalPartCode = LogicPartCode;
                    chStacking.MaterialId = orderDetail.MaterialId;
                    chStacking.MaterialCode = orderDetail.MaterialCode;
                    chStacking.MaterialName = orderDetail.MaterialName;
                    chStacking.MaterialKeyId = orderDetail.MaterialKeyId;
                    chStacking.CreateUserId = data.UserId;
                    chStacking.CreateUserName = data.UserName;
                    chStacking.BatchNo = orderDetail.BatchNo;
                    chStacking.SmallBatchNo = orderDetail.SmallBatchNo;
                    chStacking.CreateDate = DateTime.Now;
                    chStacking.Fifodate = DateTime.Now;
                    chStacking.ParentPalletBarcode = palletBarcode;
                    if (!string.IsNullOrEmpty(cellcode) && cellcode.Length > 0)
                    {
                        chStacking.ExpectedLocation = cellcode;
                    }
                    Context.TStackingStorages.Add(chStacking);
                    if (Context.SaveChanges() <= 0)
                    {
                        errMsg = "保存垛主表数据失败";
                        return false;
                    }
                    stackingId = chStacking.Id;
                }
                var allocateCell = new TCell();
                if (!string.IsNullOrEmpty(cellcode) && cellcode.Length > 0)
                {
                    allocateCell = Context.TCells.AsNoTracking().FirstOrDefault(x => x.Code == cellcode);
                    if (allocateCell == null)
                    {
                        errMsg = "仓位信息有误";
                        return false;
                    }
                    Getcell.Add(allocateCell);
                }
                else
                {
                    allocateCell = GetOneCell(station, orderDetail, heightType, out string errorMsg, palletBindMaterialModel);
                    if (allocateCell == null)
                    {
                        if (string.IsNullOrEmpty(errorMsg) || errorMsg == "")
                        {
                            errMsg = "无可用仓位";
                        }
                        else
                        {
                            errMsg = errorMsg;
                        }
                        return false;
                    }
                    Getcell.Add(allocateCell);
                    //更新托盘
                    var pall = Context.TPallets.FirstOrDefault(p => p.Id == pallet.Id);
                    pall.WarehouseId = allocateCell.Id;
                    pall.LocationCode = allocateCell.Code;
                    pall.LocationName = allocateCell.Name;
                    pall.ErplocationName = allocateCell.Erpcode;
                    pall.ModifyDate = DateTime.Now;
                    Context.TPallets.Update(pall);
                    if (Context.SaveChanges() <= 0)
                    {
                        errMsg = "更新托盘货位信息失败";
                        return false;
                    }


                    int? fullStatus = null;
                    if (orderDetail.BillType == (int)EmInBillType.EmptyPalletIn)
                    {
                        fullStatus = 5;
                    }
                    else
                    {
                        fullStatus = 1;
                    }

                    //锁仓位
                    var cell = Context.TCells.AsNoTracking().FirstOrDefault(x => x.Id == allocateCell.Id);
                    cell.BusinessType = (int)EmBusinessType.In;
                    cell.IsLock = true;
                    cell.FullStatus = (int)fullStatus;
                    cell.Status = (int)EmCellStatus.Lock;
                    cell.ModifyDate = DateTime.Now;
                    Context.TCells.Update(cell);

                    if (Context.SaveChanges() <= 0)
                    {
                        errMsg = "仓位锁定失败";
                        return false;
                    }
                    var updTss = Context.TStackingStorages.Find(chStacking.Id);
                    if (updTss == null)
                    {
                        errMsg = "找不到";
                        return false;
                    }
                    updTss.ExpectedLocation = cell.Code;
                    Context.TStackingStorages.Update(updTss);
                    if (Context.SaveChanges() <= 0)
                    {
                        errMsg = "保存垛主表数据失败";
                        return false;
                    }
                }

                //更新入库单状态
                TReceivingOrderDetail? receivingOrderDetail = Context.TReceivingOrderDetails.FirstOrDefault(r => r.Id == OrderId);
                receivingOrderDetail.LocationId = allocateCell.Id;
                receivingOrderDetail.LocationName = allocateCell.Name;
                receivingOrderDetail.LocationCode = allocateCell.Code;
                receivingOrderDetail.LogicalPartCode = allocateCell.LogicalPartCode;
                receivingOrderDetail.StackedQty = data.TotalNum;
                //Status = 3,
                receivingOrderDetail.AuditDate = DateTime.Now;
                receivingOrderDetail.AuditUserId = data.UserId;
                receivingOrderDetail.AuditUserName = data.UserName;
                Context.TReceivingOrderDetails.Update(receivingOrderDetail);
                if (Context.SaveChanges() <= 0)
                {
                    errMsg = "更新入库单失败";
                    return false;
                }
                #endregion
                result = stackingId > 0;
                if (!result)
                {
                    errMsg = "保存垛主表数据失败";
                    return false;
                }
            }
            catch (Exception ex)
            {
                errMsg = "保存组箱数据失败: " + ex.Message;
                return false;
                throw;
            }
            return true;
        }

        private (bool, string, TReceivingOrderDetail) ValidateStatus(int? orderDetailId)
        {
            TReceivingOrderDetail orderDetail = _Client.Queryable<TReceivingOrderDetail>().InSingle(orderDetailId);

            if (orderDetail == null)
            {
                return (false, "未找到入库单", null);
            }
            if (orderDetail.Status == 0 || orderDetail.Status == 1)
            {
                return (false, "入库单未审核", null);
            }
            if (orderDetail.Status == 4 || orderDetail.Status == 5)
            {
                return (false, "入库单已完成", null);
            }

            if (orderDetail.Status != 2 && orderDetail.Status != 3)
            {
                return (false, "入库单状态有误", null);
            }
            return (true, string.Empty, orderDetail);
        }
        private (bool, string, TReceivingOrderDetail) ValidateStatusEF(int? orderDetailId)
        {
            var orderObj = Context.TReceivingOrderDetails.Find(orderDetailId);
            if (orderObj == null)
            {
                return (false, "未找到入库单", null);
            }
            TReceivingOrderDetail orderDetail = orderObj;

            if (orderDetail.Status == 0 || orderDetail.Status == 1)
            {
                return (false, "入库单未审核", null);
            }
            if (orderDetail.Status == 4 || orderDetail.Status == 5)
            {
                return (false, "入库单已完成", null);
            }

            if (orderDetail.Status != 2 && orderDetail.Status != 3)
            {
                return (false, "入库单状态有误", null);
            }
            return (true, string.Empty, orderDetail);
        }

        /// <summary>
        /// 开始入库
        /// </summary>
        /// <param name="errorMsg"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public bool ExecCreateInstruct(out string errorMsg, params object[] data)
        {
            errorMsg = "";
            #region 赋值判断
            if (data == null || data.Length < 4)
            {
                errorMsg = "参数错误";
                return false;
            }         
            int heightType = (int)EmHeightType.H1150;
            TStation srcStation = data[1] as TStation;
            string ActualLocation = data[2] as string;         
            //组垛信息
            var stackstoragelist = data[3] as List<TStackingStorage>;
            if(stackstoragelist==null && !stackstoragelist.Any())
            {
                errorMsg = "组垛信息有误！";
                return false;
            }
            //上架单id
            int putid2 = 0;
            _Client.Ado.BeginTran();
            foreach (var item in stackstoragelist)
            {
                TReceivingOrderDetail orderDetail = _Client.Queryable<TReceivingOrderDetail>().First(x => x.Id == item.RelatedOrderDetailId);
                if(orderDetail==null)
                {
                    errorMsg = "入库信息有误！";
                }
                DFGK_WMS.Model.Models.PalletBindMaterialModel palletBind = new DFGK_WMS.Model.Models.PalletBindMaterialModel()
                {
                    PalletBarcode = item.PalletBarcode,
                    MaterialPackageBindModel = new DFGK_WMS.Model.Models.MaterialPackageBindModel()
                    {
                        OrderDetailId = orderDetail.Id,
                        MaterialCode = orderDetail.MaterialCode,
                        Qty = orderDetail.Qty,
                    }
                };
            //更新收货单明细表的组垛数量、保存垛主表信息、修改垛明细表的垛主表主键id
            string palletBarcode = palletBind.PalletBarcode;
            #endregion
            #region 弃用
            //if (orderDetail.SourceType == 4)
            //{
            //    var Inventories = _Client.Queryable<TInventory>().First(r => r.PalletBarcode == palletBind.PalletBarcode);
            //    if (Inventories is null)
            //    {
            //        errorMsg = "托盘未存在库存中";
            //        return false;
            //    }

            //    var stackingStorage = _Client.Queryable<TStackingStorage>().First(s => s.RelatedOrderDetailId == orderDetail.Id && s.PalletBarcode == palletBind.PalletBarcode && s.Status == 1);

            //    stackingStorage.ActualLocation = ActualLocation;
            //    if (_Client.Updateable(stackingStorage).ExecuteCommand() <= 0)
            //    {
            //        _Client.Ado.RollbackTran();
            //        errorMsg = "修改实际仓位失败";
            //        return false;
            //    }

            //    // 查看是否需要更新仓位 预留和实际的仓位是否一样
            //    if (stackingStorage.ExpectedLocation != stackingStorage.ActualLocation)
            //    {
            //        //查询托盘是为了后面更新托盘
            //        var pallet = _Client.Queryable<TPallet>().First(x => x.PalletBarcode == palletBarcode);
            //        if (pallet == null)
            //        {
            //            errorMsg = "该托盘未维护";
            //            return false;
            //        }
            //        //更新托盘
            //        var Actualcell = _Client.Queryable<TCell>().First(x => x.Code == stackingStorage.ActualLocation);

            //        var pall = _Client.Queryable<TPallet>().First(p => p.Id == pallet.Id);
            //        pall.WarehouseId = Actualcell.Id;
            //        pall.LocationCode = Actualcell.Code;
            //        pall.LocationName = Actualcell.Name;
            //        pall.ErplocationName = Actualcell.Erpcode;
            //        pall.ModifyDate = DateTime.Now;
            //        if (_Client.Updateable<TPallet>(pall).ExecuteCommand() <= 0)
            //        {
            //            errorMsg = "托盘更新失败";
            //            _Client.Ado.RollbackTran();
            //            return false;
            //        }

            //        //修改仓位
            //        var cell = _Client.Queryable<TCell>().First(x => x.Code == stackingStorage.ExpectedLocation);
            //        cell.BusinessType = (int)EmBusinessType.None;
            //        cell.IsLock = false;
            //        cell.FullStatus = 0;
            //        cell.Status = (int)EmCellStatus.Normal;
            //        cell.ModifyDate = DateTime.Now;
            //        if (_Client.Updateable<TCell>(cell).ExecuteCommand() <= 0)
            //        {
            //            errorMsg = "预留仓位修改失败";
            //            _Client.Ado.RollbackTran();
            //            return false;
            //        }
            //    }

            //    var tPutawayOrder = _Client.Queryable<TPutawayOrder>().First(s => s.RelatedOrderDetailId == Inventories.RelatedOrderDetailId);
            //    tPutawayOrder.RelatedOrderDetailId = stackingStorage.RelatedOrderDetailId;
            //    tPutawayOrder.Status = 4;
            //    var tPutawayOrderUpdCount = _Client.Updateable<TPutawayOrder>(tPutawayOrder).ExecuteCommand();
            //    if (tPutawayOrderUpdCount <= 0)
            //    {
            //        errorMsg = "修改库存仓位失败";
            //        _Client.Ado.RollbackTran();
            //        return false;
            //    }
            //    //修改库存的信息(修改组垛仓位)
            //    var cellObj = _Client.Queryable<TCell>().First(s => s.Code == stackingStorage.ActualLocation);
            //    if (cellObj == null)
            //    {
            //        errorMsg = "找不到仓位code:" + stackingStorage.ActualLocation;//修改组垛仓位
            //        _Client.Ado.RollbackTran();
            //        return false;
            //    }

            //    Inventories.LocationCode = cellObj.Code;
            //    Inventories.LocationName = cellObj.Name;
            //    Inventories.LocationId = cellObj.Id;
            //    Inventories.RelatedOrderDetailId = stackingStorage.RelatedOrderDetailId;
            //    Inventories.Status = 3;//修改库存状态为入库在途
            //    /*Inventories.TotalWeight = palletBind.MaterialPackageBindModel.Qty * GetMaterialTonnagefactor(orderDetail.MaterialCode);*///总重量等于入库数量 * 物料吨数系数
            //    var count = _Client.Updateable<TInventory>(Inventories).ExecuteCommand();
            //    if (count <= 0)
            //    {
            //        errorMsg = "修改库存仓位失败";
            //        _Client.Ado.RollbackTran();
            //        return false;
            //    }


            //    if (orderDetail.Qty == orderDetail.StackedQty)
            //    {
            //        var Instructobj = _Client.Queryable<TInstruct>().First(i => i.RelatedOrderDetailId == orderDetail.Id);
            //        if (Instructobj is null)
            //        {
            //            errorMsg = "指令表查询错误";
            //            _Client.Ado.RollbackTran();
            //            return false;
            //        }
            //        var isok = ExecInstructFinished(Instructobj, out errorMsg);
            //        if (!isok)
            //        {
            //            errorMsg = errorMsg;
            //            _Client.Ado.RollbackTran();
            //            return false;
            //        }
            //        _Client.Ado.CommitTran();
            //        return true;
            //    }
            //    else
            //    {
            //        errorMsg = "组垛数量和入库数量不一致";
            //        _Client.Ado.RollbackTran();
            //        return false;
            //    }
            //}
            #endregion
            TInstruct instruct = null;
            List<string> packageBarcodes = new List<string>();

            int cellId;
            TCell allocateCell = null;
            decimal? materialNum = 0;
            decimal? price = 0;
                lock (_lockObj)
                {
                    bool result = false;
                    TPallet pallet = null;

                    bool invCount = _Client.Queryable<TInventory>().Any(x => x.Status == 1 && x.PalletBarcode == palletBarcode);
                    if (invCount)
                    {
                        errorMsg = "当前垛已经存在库存";
                        return false;
                    }
                    if (orderDetail.Status == (int)EmBillStatus.Create)
                    {
                        errorMsg = "入库单未启动";
                        return false;
                    }
                    if (orderDetail.Status == (int)EmBillStatus.Finished || orderDetail.Status == (int)EmBillStatus.MandatoryFinished)
                    {
                        errorMsg = "入库单已完成";
                        return false;
                    }
                    if (orderDetail.Status != (int)EmBillStatus.Executing)
                    {
                        errorMsg = "当前入库单未执行";
                        return false;
                    }
                    if (orderDetail.Price.HasValue)
                    {
                        price = orderDetail.Price;
                    }
                    bool outInstructCount = _Client.Queryable<TInstruct>().Any(x => x.WarehouseCode == orderDetail.WarehouseCode && x.Status == 2 && x.BusinessType == (int)EmBusinessType.Out && x.IsSuspend == false && x.ExpectedToLocation == srcStation.Code);
                    if (outInstructCount)
                    {
                        errorMsg = "有出库指令未完成，不能执行入库";
                        return false;
                    }
                    TMaterial material = _Client.Queryable<TMaterial>().First(x => x.Id == orderDetail.MaterialId);
                    if (material == null)
                    {
                        errorMsg = "订单明细物料数据不存在";
                        return false;
                    }
                    pallet = _Client.Queryable<TPallet>().First(x => x.PalletBarcode == palletBarcode);
                    if (pallet == null)
                    {
                        errorMsg = "该托盘未维护";
                        return false;
                    }
                    if (pallet.Status == 0)
                    {
                        errorMsg = "该托盘已被禁用";
                        return false;
                    }

                    var stackingStorage = _Client.Queryable<TStackingStorage>().First(s => s.RelatedOrderDetailId == orderDetail.Id && s.PalletBarcode == palletBind.PalletBarcode && s.Status == 1);
                    stackingStorage.ActualLocation = ActualLocation;
                    if (_Client.Updateable(stackingStorage).ExecuteCommand() <= 0)
                    {
                        errorMsg = "修改实际仓位失败";
                        return false;
                    }

                    // 查看是否需要更新仓位 预留和实际的仓位是否一样
                    if (stackingStorage.ExpectedLocation != stackingStorage.ActualLocation)
                    {
                        //更新托盘
                        var Actualcell = _Client.Queryable<TCell>().First(x => x.Code == stackingStorage.ActualLocation);

                        var pall = _Client.Queryable<TPallet>().First(p => p.Id == pallet.Id);
                        pall.WarehouseId = Actualcell.Id;
                        pall.LocationCode = Actualcell.Code;
                        pall.LocationName = Actualcell.Name;
                        pall.ErplocationName = Actualcell.Erpcode;
                        pall.ModifyDate = DateTime.Now;
                        if (_Client.Updateable<TPallet>(pall).ExecuteCommand() <= 0)
                        {
                            errorMsg = "托盘更新失败";
                            return false;
                        }

                        //修改仓位
                        var cell = _Client.Queryable<TCell>().First(x => x.Code == stackingStorage.ExpectedLocation);
                        cell.BusinessType = (int)EmBusinessType.None;
                        cell.IsLock = false;
                        cell.FullStatus = 0;
                        cell.Status = (int)EmCellStatus.Normal;
                        cell.ModifyDate = DateTime.Now;
                        if (_Client.Updateable<TCell>(cell).ExecuteCommand() <= 0)
                        {
                            errorMsg = "预留仓位修改失败";
                            return false;
                        }
                    }
                    #region 逻辑分区
                    if (stackingStorage == null || string.IsNullOrEmpty(stackingStorage.LogicalPartCode))
                    {
                        errorMsg = "未选择逻辑分区";
                        return false;
                    }
                    if (stackingStorage.LogicalPartCode == "Box8060" && pallet.Type != 1)
                    {
                        errorMsg = "逻辑分区与料箱不匹配";
                        return false;
                    }
                    else if (stackingStorage.LogicalPartCode == "Box6040" && pallet.Type != 2)
                    {
                        errorMsg = "逻辑分区与料箱不匹配";
                        return false;
                    }
                    #endregion
                    #region 无用
                    //var stackingstorage = _Client.Queryable<TStackingStorage>().First(x => x.PalletBarcode == palletBarcode);
                    allocateCell = _Client.Queryable<TCell>().First(c => c.Code == stackingStorage.ActualLocation); //修改组垛仓位

                    //decimal? putawayQTY = _Client.Queryable<TPutawayOrder>().Where(p => p.SourceType == 1 && p.RelatedOrderDetailId == orderDetail.Id).Sum(t => t.Qty).GetValueOrDefault();
                    //最小库存单位
                    materialNum = palletBind.MaterialPackageBindModel.Qty;
                    //   int boxNum = palletBind.MaterialPackageBindModels.Where(t => t != null).Sum(t => t.PackageCount);
                    //_Client.Ado.BeginTran();
                    #endregion
                    bool hasSkuDetail = true;
                    int stackingStorageId = _Client.Queryable<TStackingStorage>().First(s => s.PalletBarcode == palletBarcode && s.MaterialId == orderDetail.MaterialId && s.WarehouseCode == orderDetail.WarehouseCode && s.RelatedOrderDetailId == orderDetail.Id).Id;

                    var receivingOrderDetail = _Client.Queryable<TReceivingOrderDetail>().First(x => x.Id == orderDetail.Id);
                    receivingOrderDetail.Status = 2;
                    //生成wms指令
                    instruct = new TInstruct
                    {
                        WarehouseCode = "A2",
                        Status = 2,
                        FromLocation = "",
                        ToLocation = allocateCell.Code,
                        StackingStorageId = stackingStorageId,
                        WorkDeviceType = receivingOrderDetail.RefInVoucherId == 0 ? 1 : 2,
                        InstructType = 1,
                        Action = 0,
                        RelatedOrderId = orderDetail.Id,
                        DeviceCode = "",
                        ExpectedToLocation = allocateCell.Code,
                        InstructIndex = 1,
                        PalletBarcode = palletBarcode,
                        ScanedBarcode = palletBarcode,
                        Priority = 9999,
                        Qty = (decimal)materialNum,
                        FinishedQty = 0,
                        StartTime = DateTime.Now,
                        BusinessGroupId = Guid.NewGuid(),
                        BusinessType = (int)EmBusinessType.In,
                        BillType = (int)orderDetail.BillType.GetValueOrDefault(),
                        LogicalCellAddr = allocateCell.Erpcode
                    };
                    int instructId = _Client.Insertable<TInstruct>(instruct).ExecuteReturnIdentity();

                    if (instructId <= 0)
                    {
                        errorMsg = "指令保存失败";
                        _Client.Ado.RollbackTran();
                        return false;
                    }
                    instruct.Id = instructId;

                    //保存库存
                    TInventory inventory = new TInventory()
                    {
                        WarehouseId = allocateCell.WhId,
                        WarehouseCode = allocateCell.WhCode,
                        WarehouseName = allocateCell.WhName,
                        AreaCode = allocateCell.AreaCode,
                        AreaName = allocateCell.AreaName,
                        AreaId = allocateCell.AreaId,
                        LocationId = allocateCell.Id,
                        LocationCode = allocateCell.Code,
                        LocationDepth = allocateCell.DepthIndex,
                        LocationName = allocateCell.Name,
                        Status = 3,
                        PalletBarcode = palletBarcode,
                        ParentPalletBarcode = stackingStorage.ParentPalletBarcode,
                        RelatedOrderDetailId = orderDetail.Id,
                        BillType = (int)orderDetail.BillType.GetValueOrDefault(),
                        IsLock = true,
                        CreateDate = DateTime.Now,
                        MaterialId = orderDetail.MaterialId,
                        MaterialCode = orderDetail.MaterialCode,
                        MaterialName = orderDetail.MaterialName,
                        CustomerId = orderDetail.CustomerId,
                        CustomerName = orderDetail.CustomerName,
                        SupplierId = orderDetail.SupplierId,
                        SupplierName = orderDetail.SupplierName,
                        HasSkuDetail = hasSkuDetail,
                        PutawayQty = materialNum,
                        UnitId = orderDetail.UnitId,
                        UnitName = orderDetail.UnitName,
                        MaterialKeyId = orderDetail.MaterialKeyId,
                        BatchNo = orderDetail.BatchNo,
                        SmallBatchNo = orderDetail.SmallBatchNo,
                        OwnerId = orderDetail.OwnerId,
                        OwnerName = orderDetail.OwnerName,
                        ExpireDate = orderDetail.ExpireDate,
                        ProductDate = orderDetail.ProductDate,
                        MaterialTypeCode = orderDetail.MaterialTypeCode,
                        MaterialTypeName = orderDetail.MaterialTypeName,
                        PickedQty = 0,
                        PackQty = packageBarcodes.Count,
                        ErplocationCode = allocateCell.Erpcode,
                        RoutewayId = allocateCell.RoutewayId,
                        StackingStorageId = stackingStorageId,
                        LocationHeightType = allocateCell.HeightType,
                        RealHeightType = heightType,
                        LogicalPartCode = orderDetail.LogicalPartCode,//按单据来
                        LocationColumnNo = allocateCell.ColumnNo,
                        LocationLayerNo = allocateCell.LayerNo,
                        LocationDistanceValue = allocateCell.DistanceValue,
                        LocationLineNo = allocateCell.LineNo,
                        DeptCode = orderDetail.DeptCode,
                        DeptName = orderDetail.DeptName,
                        TotalPrice = price * materialNum,
                        Price = price,
                        AvailableQty = palletBind.MaterialPackageBindModel.Qty,
                        AllocateQty = 0,
                        //
                        Remark = orderDetail.Remark,
                        //
                        DictReceiving = orderDetail.BatchNoExplain,
                    };
                    var inventoryId = _Client.Insertable<TInventory>(inventory).ExecuteReturnBigIdentity();
                    if (inventoryId <= 0)
                    {
                        errorMsg = "库存主表保存失败";
                        _Client.Ado.RollbackTran();
                        return false;
                    }
                    var putobj = _Client.Queryable<TPutawayOrder>().First(x => x.SourceType == 1 && x.Status == 4 && x.PalletBarcode==palletBarcode && x.BillType==null);
                    if (putobj == null)
                    {
                        //保存上架单主表             
                        string str = DateTime.Now.ToString("yyyyMMddHHmmssfff");// + randNum.ToString("0000");
                        string putawayCode = "PUT" + str;
                        var cellList = Context.TCells.Where(x => x.Code == allocateCell.Code);
                        if (cellList.Count() <= 0)
                        {
                            errorMsg = "暂无仓位" + allocateCell.Code;
                            _Client.Ado.RollbackTran();
                            return false;
                        }
                        int a, b;
                        string code = "";
                        MatchCollection match = Regex.Matches(ActualLocation, @"\d");
                        if (match.Count >= 2)
                        {
                            a = Convert.ToInt32(match[0].Value);
                            b = Convert.ToInt32(match[1].Value);
                            if (a == 4 && (a + b == 5 || a + b == 6))
                            {
                                code = "1806";
                            }
                        }
                        TPutawayOrder putawayOrder = new TPutawayOrder();
                        putawayOrder.Code = putawayCode;
                        putawayOrder.RelatedOrderDetailId = orderDetail.Id;
                        putawayOrder.StackingStorageId = stackingStorageId;
                        putawayOrder.PalletBarcode = palletBarcode;
                        putawayOrder.ParentPalletBarcode = stackingStorage.ParentPalletBarcode;
                        putawayOrder.LocationCode = allocateCell.Code;
                        putawayOrder.LocationDepth = allocateCell.DepthIndex == 0 ? null : allocateCell.DepthIndex;
                        putawayOrder.Status = 4;
                        putawayOrder.Qty = materialNum;
                        putawayOrder.CreateDate = DateTime.Now;
                        putawayOrder.MaterialId = orderDetail.MaterialId;
                        putawayOrder.MaterialCode = orderDetail.MaterialCode;
                        putawayOrder.MaterialName = orderDetail.MaterialName;
                        putawayOrder.MaterialKeyId = orderDetail.MaterialKeyId;
                        putawayOrder.BatchNo = orderDetail.BatchNo;
                        putawayOrder.SmallBatchNo = orderDetail.SmallBatchNo;
                        putawayOrder.OwnerId = orderDetail.OwnerId;
                        putawayOrder.OwnerName = orderDetail.OwnerName;
                        putawayOrder.CreateUserId = 0;
                        putawayOrder.CreateUserName = "系统";
                        putawayOrder.SourceType = 1;
                        //站点编码
                        if (!string.IsNullOrEmpty(code) && code.Length > 0)
                        {
                            putawayOrder.SiteCode = "1800";
                            putawayOrder.Roadway = code;
                        }
                        else
                        {
                            //巷道
                            putawayOrder.Roadway = cellList.FirstOrDefault().RoutewayId.ToString();
                            putawayOrder.SiteCode = data[4] as string;
                        }

                        var putId = _Client.Insertable<TPutawayOrder>(putawayOrder).ExecuteReturnBigIdentity();
                        if (putId <= 0)
                        {
                            errorMsg = "上架单主表保存失败";
                            _Client.Ado.RollbackTran();
                            return false;
                        }
                        putid2 = putawayOrder.Id;

                        #region 呼叫agv
                        if (orderDetail.RefInVoucherId == 1 && orderDetail.Erpcode != "DN采购收货-交货单")
                        {
                            var trebill = Context.TReceivingBills.AsNoTracking().FirstOrDefault(x => x.Id == orderDetail.ReceivingBillId);
                            if (trebill == null)
                            {
                                errorMsg = "生产入库信息有误！";
                                _Client.Ado.RollbackTran();
                                return false;
                            }
                            string? first = "";
                            string? last = "";
                            int pallcount = orderDetail.Remark.Split(',').Count();
                            //调用agv
                            AgvRequst agvRequst = new AgvRequst();
                            agvRequst.taskCode = putawayCode;
                            agvRequst.tasktype = "1";
                            agvRequst.pickingNo = trebill.RefSn;
                            agvRequst.pickingLineNumber = trebill.DictReceiving;
                            agvRequst.abnormalTitle = (pallcount + 1).ToString();
                            if (orderDetail.BatchNoExplain != null && orderDetail.BatchNoExplain.Length > 0)
                            {
                                first = orderDetail.BatchNoExplain.Split(',').FirstOrDefault();
                                last = orderDetail.BatchNoExplain.Split(',').LastOrDefault();
                            }
                            else
                            {
                                errorMsg = "收货数量有误";
                                _Client.Ado.RollbackTran();
                                return false;
                            }
                            PalletMsg palletMsg = new PalletMsg();
                            palletMsg.palletcode = orderDetail.PalletBarcode;
                            palletMsg.materialcode = orderDetail.MaterialCode;
                            palletMsg.materialname = orderDetail.MaterialName;
                            if (orderDetail.BatchNoExplain != null && orderDetail.BatchNoExplain.Length > 1)
                            {
                                palletMsg.materialqulitity = (orderDetail.Qty - Convert.ToDecimal(first) - Convert.ToDecimal(last)).ToString();
                            }
                            else
                            {
                                palletMsg.materialqulitity = (orderDetail.Qty - Convert.ToDecimal(first)).ToString();
                            }

                            agvRequst.Pallet.Add(palletMsg);
                            int count = 0;
                            foreach (var item2 in orderDetail.Remark.Split(','))
                            {
                                PalletMsg palletMsg2 = new PalletMsg();
                                if (pallcount == 1 && !string.IsNullOrEmpty(orderDetail.Remark) && orderDetail.Remark.Length > 0)
                                {
                                    palletMsg2.palletcode = orderDetail.Remark;
                                }
                                else
                                {
                                    palletMsg2.palletcode = item2;
                                }
                                palletMsg2.materialcode = orderDetail.MaterialCode;
                                palletMsg2.materialname = orderDetail.MaterialName;
                                if (count == 0)
                                    palletMsg2.materialqulitity = first;
                                else
                                    palletMsg2.materialqulitity = last;
                                agvRequst.Pallet.Add(palletMsg2);
                                count++;
                            }
                            var agvdt = HttpHelper.AgvSendPostRequest("script-api/getTaskByWms", agvRequst);
                        }
                        else if (orderDetail.MaterialName == "中转区空托盘")
                        {
                            //调用agv
                            int pallcount = orderDetail.Remark.Split(',').Count();
                            AgvRequst agvRequst = new AgvRequst();
                            agvRequst.taskCode = putawayCode;
                            agvRequst.tasktype = "1";
                            agvRequst.pickingNo = receivingOrderDetail.OrderSn;
                            agvRequst.pickingLineNumber = "";
                            agvRequst.abnormalTitle = (pallcount).ToString();
                            int count = 0;
                            foreach (var item2 in orderDetail.Remark.Split(','))
                            {
                                PalletMsg palletMsg2 = new PalletMsg();
                                if (pallcount == 1 && !string.IsNullOrEmpty(orderDetail.Remark) && orderDetail.Remark.Length > 0)
                                {
                                    palletMsg2.palletcode = orderDetail.Remark;
                                }
                                else
                                {
                                    palletMsg2.palletcode = item2;
                                }
                                palletMsg2.materialcode = orderDetail.MaterialCode;
                                palletMsg2.materialname = orderDetail.MaterialName;
                                palletMsg2.materialqulitity = "0";
                                agvRequst.Pallet.Add(palletMsg2);
                                count++;
                            }
                            var agvdt = HttpHelper.AgvSendPostRequest("script-api/getTaskByWms", agvRequst);
                        }
                        #endregion
                    }
                    else
                        putid2 = putobj.Id;
                    #region 废弃
                        //if (palletBind.MaterialPackageBindModel.Barcodes != null && palletBind.MaterialPackageBindModel.Barcodes.Count > 0)
                        //{

                        //    List<TPackageDetail> packageDetailList = _Client.Queryable<TPackageDetail>().Where(p => p.RelatedOrderDetailId == orderDetail.Id && p.StackingStorageId == stackingStorageId && p.PackageCode == palletBarcode).ToList();
                        //    var packageDetail = packageDetailList.FirstOrDefault(t => t.PackageClass == 1 && t.ParentId == 0);
                        //    foreach (var item in palletBind.MaterialPackageBindModel.Barcodes)
                        //    {
                        //        //库存明细保存
                        //        TInventoryDetail inventoryDetail = new TInventoryDetail()
                        //        {
                        //            InventoryId = (int)inventoryId,
                        //            Barcode = item,
                        //            PackageBarcode = palletBarcode,
                        //            PalletBarcode = palletBarcode,
                        //            CreateDate = DateTime.Now,
                        //            SkuNum = 1,
                        //            Price = price,
                        //            TotalPrice = price * 1,
                        //            IsSku = true,
                        //        };

                        //        var inventoryDetailId = _Client.Insertable<TInventoryDetail>(inventoryDetail).ExecuteReturnBigIdentity();
                        //        if (inventoryDetailId <= 0)
                        //        {
                        //            errorMsg = "库存明细表保存失败";
                        //            _Client.Ado.RollbackTran();
                        //            return false;
                        //        }
                        //        //上架单明细表保存
                        //        TPutawayOrderDetail putawaydetail = new TPutawayOrderDetail()
                        //        {
                        //            //PutawayOrderId = (int)putId,
                        //            PalletBarcode = palletBarcode,
                        //            PackageBarcode = palletBarcode,// package.PackageBarcode
                        //            MaterialBarcode = item,
                        //        };
                        //        var putDetailId = _Client.Insertable<TPutawayOrderDetail>(putawaydetail).ExecuteReturnBigIdentity();
                        //        if (putDetailId < 0)
                        //        {
                        //            errorMsg = "上架单明细表保存失败";
                        //            _Client.Ado.RollbackTran();
                        //            return false;
                        //        }
                        //        if (packageDetail != null)
                        //        {
                        //            if (packageDetailList.Any(t => t.Barcode == item))
                        //            {
                        //                continue;
                        //            }
                        //            TPackageDetail package = new TPackageDetail()
                        //            {
                        //                Status = 1,
                        //                RelatedOrderDetailId = orderDetail.Id,
                        //                MaterialId = orderDetail.MaterialId,
                        //                MaterialKeyId = orderDetail.MaterialKeyId,
                        //                MaterialCode = orderDetail.MaterialCode,
                        //                MaterialName = orderDetail.MaterialName,
                        //                PackageClass = 2,
                        //                BatchNo = orderDetail.BatchNo,
                        //                SmallBatchNo = orderDetail.SmallBatchNo,
                        //                Qty = 1,
                        //                UnitId = orderDetail.UnitId,
                        //                UnitName = orderDetail.UnitName,
                        //                ConvertFigre = 0,
                        //                Barcode = item,
                        //                PackageCode = palletBarcode,
                        //                LayerIndex = 1,
                        //                CreateDate = DateTime.Now,
                        //                StackingStorageId = stackingStorageId,
                        //                ParentId = packageDetail.Id,
                        //                IsStocktake = false,
                        //                CreateUserId = packageDetail.CreateUserId,
                        //                CreateUserName = packageDetail.CreateUserName,
                        //            };
                        //            var skuPkgId = _Client.Insertable<TPackageDetail>(package).ExecuteReturnBigIdentity();
                        //            if (skuPkgId <= 0)
                        //            {
                        //                errorMsg = "保存组箱数据失败";
                        //                _Client.Ado.RollbackTran();
                        //                return false;
                        //            }
                        //        }
                        //    }
                        //    //更新入库单货品明细
                        //    var receivingGoodDetailList = _Client.Queryable<TReceivingGoodsDetail>().Where(r => r.OrderDetailId == orderDetail.Id && palletBind.MaterialPackageBindModel.Barcodes.Contains(r.Barcode)).ToList();
                        //    if (receivingGoodDetailList.Count != palletBind.MaterialPackageBindModel.Barcodes.Count)
                        //    {
                        //        errorMsg = "货品明细与组垛明细数量不一致";
                        //        _Client.Ado.RollbackTran();
                        //        return false;
                        //    }
                        //    else
                        //    {
                        //        foreach (var item in receivingGoodDetailList)
                        //        {
                        //            item.Status = 1;
                        //            item.PalletBarcode = palletBarcode;
                        //            item.PackageBarcode = palletBarcode;
                        //            _Client.Updateable<TReceivingGoodsDetail>(item);
                        //        }
                        //    }
                        //}
                        #endregion
                        //上架单明细表保存
                    TPutawayOrderDetail putawayOrderDetail = new TPutawayOrderDetail()
                    {
                        PutawayOrderId = putid2,
                        PalletBarcode = palletBarcode,
                        PackageBarcode = palletBarcode,//package.PackageBarcode
                        MaterialBarcode = orderDetail.MaterialCode,
                    };
                    var putDetailId = _Client.Insertable<TPutawayOrderDetail>(putawayOrderDetail).ExecuteReturnBigIdentity();

                    if (putDetailId < 0)
                    {
                        errorMsg = "上架单明细表保存失败";
                        _Client.Ado.RollbackTran();
                        return false;
                    }
                    //库存明细保存
                    TInventoryDetail inventoryDetail = new TInventoryDetail()
                    {
                        InventoryId = (int)inventoryId,
                        Barcode = "",
                        PackageBarcode = palletBarcode,// package.PackageBarcode
                        PalletBarcode = palletBarcode,
                        CreateDate = DateTime.Now,
                        SkuNum = materialNum,
                        IsSku = false,
                        Price = price,
                        TotalPrice = price * materialNum
                    };
                    var inventoryDetailId = _Client.Insertable<TInventoryDetail>(inventoryDetail).ExecuteReturnBigIdentity();
                    if (inventoryDetailId < 0)
                    {
                        errorMsg = "库存明细表保存失败";
                        _Client.Ado.RollbackTran();
                        return false;
                    }
                }
            }
            _Client.Ado.CommitTran();
            return true;
        }
        /// <summary>
        /// 完成入库
        /// </summary>
        /// <param name="instruct"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        private bool ExecInstructFinished(TInstruct instruct, out string errorMsg)
        {
            //越飞
            //var instrobj = Context.TInstructs.AsQueryable();
            //.FirstOrDefault(x => x.RelatedOrderId == 0 && x.PalletBarcode == "" && x.Status == 2);
            errorMsg = "";
            if (string.IsNullOrEmpty(instruct.PalletBarcode))
            {
                errorMsg = "参数错误";
                return false;
            }
            lock (_lockObj)
            {
                try
                {
                    var orderDetail = _Client.Queryable<TReceivingOrderDetail>().First(r => r.Id == instruct.RelatedOrderId);
                    if (orderDetail == null)
                    {
                        errorMsg = "入库单明细不存在";
                        return false;
                    }
                    var inventory = _Client.Queryable<TInventory>().First(i => i.PalletBarcode == instruct.PalletBarcode);
                    if (inventory == null)
                    {
                        errorMsg = "库存数据不存在";
                        return false;
                    }
                    List<TInventoryDetail> inventoryDetailList = _Client.Queryable<TInventoryDetail>().Where(i => i.InventoryId == inventory.Id).ToList();
                    if (inventoryDetailList == null || inventoryDetailList.Count == 0)
                    {
                        errorMsg = "库存明细数据不存在";
                        return false;
                    }
                    List<string> packageBarcodes = inventoryDetailList.Select(t => t.PackageBarcode).Distinct().ToList();
                    TCell cell = _Client.Queryable<TCell>().First(c => c.Code == instruct.ExpectedToLocation);
                    if (cell == null)
                    {
                        errorMsg = "仓位数据不存在";
                        return false;
                    }
                    DateTime? now = DateTime.Now;
                    bool result = false;
                    #region 事务处理
                    _Client.Ado.BeginTran();
                    instruct.Status = 4;
                    instruct.EndTime = DateTime.Now;
                    result = _Client.Updateable<TInstruct>(instruct).ExecuteCommand() > 0;
                    if (!result)
                    {
                        _Client.Ado.RollbackTran();
                        errorMsg = "指令插入失败";
                        return false;
                    }
                    var putawayOrder = _Client.Queryable<TPutawayOrder>().First(p => p.Status == 4 && p.RelatedOrderDetailId == orderDetail.Id && p.StackingStorageId == instruct.StackingStorageId);
                    putawayOrder.Status = 5;
                    putawayOrder.Fifodate = now;
                    var count = _Client.Updateable<TPutawayOrder>(putawayOrder).ExecuteCommand();
                    if (count <= 0)
                    {
                        errorMsg = "上架单状态修改失败";
                        _Client.Ado.RollbackTran();
                        return false;
                    }

                    var inventory1 = _Client.Queryable<TInventory>().First(i => i.Id == inventory.Id);
                    inventory1.Status = 1;
                    inventory1.AllocateQty = instruct.Qty;
                    inventory1.InStockDate = now;
                    inventory1.InStockShortDate = Convert.ToInt32(now.Value.ToString("yyyyMMdd"));
                    inventory1.PutawayQty = instruct.Qty;
                    inventory1.IsLock = false;
                    count = _Client.Updateable<TInventory>(inventory1).ExecuteCommand();
                    if (count <= 0)
                    {
                        errorMsg = "库存状态修改失败";
                        _Client.Ado.RollbackTran();
                        return false;
                    }
                    var cell1 = _Client.Queryable<TCell>().First(c => c.Id == inventory.LocationId);
                    cell1.IsLock = false;
                    cell1.BusinessType = 0;
                    cell1.Status = 1;
                    cell1.FullStatus = 1;
                    cell1.ModifyDate = now;
                    count = _Client.Updateable<TCell>(cell1).ExecuteCommand();
                    if (count <= 0)
                    {
                        errorMsg = "仓位状态修改失败";
                        _Client.Ado.RollbackTran();
                        return false;
                    }
                    //查询组垛
                    bool isUpdateOrderDetail = true;
                    //List<string> palletBarcodes = new List<string>();
                    //var stackingStorage = _Client.Queryable<TStackingStorage>().First(s => s.Status == 1 && s.PalletBarcode == inventory.PalletBarcode);
                    //List<TStackingStorage> stackingStorageModels = _Client.Queryable<TStackingStorage>().Where(s => s.Status == 1 && (s.PalletBarcode == stackingStorage.PalletBarcode || s.ParentPalletBarcode == stackingStorage.PalletBarcode)).ToList();
                    //if (stackingStorageModels.Count > 1)
                    //{
                    //    //拆卸
                    //    palletBarcodes = stackingStorageModels.Select(t => t.PalletBarcode).Distinct().ToList();
                    //    count = _Client.Queryable<TInventory>().Where(i => i.Status == 1 && i.IsLock == false && palletBarcodes.Contains(i.PalletBarcode)).Count();
                    //    if (palletBarcodes.Count == count)
                    //    {
                    //        isUpdateOrderDetail = true;
                    //    }
                    //    else
                    //    {
                    //        isUpdateOrderDetail = false;
                    //    }
                    //}
                    if (isUpdateOrderDetail)
                    {
                        decimal? totalPutawayQTY = _Client.Queryable<TPutawayOrder>().Where(t => t.SourceType == 1 && t.RelatedOrderDetailId == orderDetail.Id && t.Status == 5).Sum(t => t.Qty);
                        TReceivingOrderDetail modifyOrderDetail = new TReceivingOrderDetail
                        {
                            ReceivedQty = totalPutawayQTY,
                            InStarDate = orderDetail.InStarDate == null ? now : orderDetail.InStarDate,
                        };
                        if (totalPutawayQTY.GetValueOrDefault() >= orderDetail.Qty.GetValueOrDefault())
                        {
                            modifyOrderDetail.Status = (int)EmBillStatus.Finished;
                        }

                        var receivingOrderDetail = _Client.Queryable<TReceivingOrderDetail>().First(r => r.Id == orderDetail.Id);
                        receivingOrderDetail.ReceivedQty = modifyOrderDetail.ReceivedQty;
                        receivingOrderDetail.InStarDate = modifyOrderDetail.InStarDate;
                        receivingOrderDetail.Status = modifyOrderDetail.Status;
                        count = _Client.Updateable<TReceivingOrderDetail>(receivingOrderDetail).ExecuteCommand();
                        if (count <= 0)
                        {
                            errorMsg = "订单明细修改失败";
                            _Client.Ado.RollbackTran();
                            return false;
                        }
                    }
                    //保存库存日志表
                    //int logId = inventoryLogService.InsertInventoryLog(context, 
                    //如果是回流入库就不填库存流水
                    if (orderDetail.SourceType == 4)
                    {
                        //数量的修改可以先把库存数量修改为0 然后把需要修改的数据赋到入库单上
                        _Client.Ado.CommitTran();
                        return true;
                    }
                    TInventoryLog inventoryLog = new TInventoryLog()
                    {
                        SourceType = 0,
                        SourceSn = orderDetail.OrderSn,
                        WarehouseId = orderDetail.WarehouseId,
                        WarehouseName = orderDetail.WarehouseName,
                        AreaName = inventory.AreaName,
                        AreaId = inventory.AreaId,
                        LocationCode = inventory.LocationCode,
                        PalletBarcode = instruct.PalletBarcode,
                        OwnerId = orderDetail.OwnerId,
                        OwnerName = orderDetail.OwnerName,
                        MaterialId = orderDetail.MaterialId,
                        MaterialCode = orderDetail.MaterialCode,
                        MaterialName = orderDetail.MaterialName,
                        BatchNo = orderDetail.BatchNo,
                        SmallBatchNo = orderDetail.SmallBatchNo,
                        StartQty = 0,
                        ChangeQty = instruct.Qty,
                        EndQty = instruct.Qty,
                        BaseUnitId = orderDetail.UnitId,
                        BaseUnitName = orderDetail.UnitName,
                        CreateDate = DateTime.Now,
                    };
                    int logId = _Client.Insertable<TInventoryLog>(inventoryLog).ExecuteReturnIdentity();
                    if (logId < 0)
                    {
                        errorMsg = "库存日志表保存失败";
                        _Client.Ado.RollbackTran();
                        return false;
                    }
                    _Client.Ado.CommitTran();
                    return true;
                    #endregion
                }
                catch (Exception)
                {
                    _Client.Ado.RollbackTran();
                    throw;
                }
            }
        }

        /// <summary>
        /// 获取一个仓位
        /// </summary>
        /// <returns></returns>
        private TCell GetOneCell(TStation srcStation, TReceivingOrderDetail orderDetail, int heightType, out string errorMsg, Model.Models.PalletBindMaterialModel palletBindMaterialModel)
        {
            var stackingStorage = Context.TStackingStorages.FirstOrDefault(s => s.BatchNo == orderDetail.BatchNo && s.MaterialId == orderDetail.MaterialId && s.WarehouseCode == orderDetail.WarehouseCode && s.RelatedOrderDetailId == orderDetail.Id && s.PalletBarcode == palletBindMaterialModel.PalletBarcode);
            var pallet = Context.TPallets.FirstOrDefault(x => x.PalletBarcode == palletBindMaterialModel.PalletBarcode);

            if (stackingStorage == null || string.IsNullOrEmpty(stackingStorage.LogicalPartCode))
            {
                errorMsg = "未选择逻辑分区";
                return null;
            }
            if (stackingStorage.LogicalPartCode == "Box8060" && pallet.Type != 1)
            {
                errorMsg = "逻辑分区与料箱不匹配";
                return null;
            }
            else if (stackingStorage.LogicalPartCode == "Box6040" && pallet.Type != 2)
            {
                errorMsg = "逻辑分区与料箱不匹配";
                return null;
            }

            var allocateCell = TCellRepository.AllocateCell(srcStation, (int)orderDetail.MaterialId.GetValueOrDefault(), (int)orderDetail.RefInVoucherId.GetValueOrDefault(), orderDetail.QualityState, heightType, out errorMsg, stackingStorage.LogicalPartCode);

            return allocateCell;
        }
    }
}
